import codecs

import requests
import threading
import json

from db.sqlite.sqlite import sqlite
import result

apiPath = {"stable_token": {"path": "https://apiweixin.webusi.net/cgi-bin/stable_token", "desc": "获取稳定版接口调用凭据"},
           "add_material": {"path": "https://apiweixin.webusi.net/cgi-bin/add_material", "desc": "上传永久素材"},
           "get_materialcount": {"path": "https://api.weixin.qq.com/cgi-bin/material/get_materialcount", "desc": "获取永久素材总数"},
           "batchget_material": {"path": "https://api.weixin.qq.com/cgi-bin/material/batchget_material", "desc": "获取永久素材列表"},
           "get_key": {"path": "get_key", "desc": "获取密钥"},
           "set_key": {"path": "set_key", "desc": "设置密钥"},
           "get_db": {"path": "get_db", "desc": "获取数据库"},
           "set_db": {"path": "set_db", "desc": "设置数据库"}
}

class WeChat:
    def __init__(self, appId=None, appSecret=None):
        self.appId = appId
        self.appSecret = appSecret
        self.inited = False
        self.taskStarted = False

    def task(self):
        result = self.stable_token()
        tokenJson = json.loads(result)
        self.accessToken = tokenJson['access_token']

    def startTask(self):
        t = threading.Timer(3600, self.task())
        t.start()
        self.taskStarted = True

    def set_key(self, appId, appSecret):
        self.appId = appId
        self.appSecret = appSecret
        if sqlite.path != None:
            sql = "SELECT name FROM sqlite_master WHERE type='table' AND name='sys_config'"
            values = sqlite.select(sql)
            if values==None or len(values)==0:
                sql = '''CREATE TABLE IF NOT EXISTS sys_config 
                (id INTEGER PRIMARY KEY AUTOINCREMENT,                   
                code TEXT NOT NULL, 
                content TEXT NOT NULL)'''
                sqlite.executeOne(sql)

            sql = "select * from sys_config where code in('appId','appSecret')"
            values = sqlite.select(sql)

            if values == None or len(values)==0:
                sql = "insert into sys_config(code, content) values(?,?)"
                values = [("appId", appId), ("appSecret", appSecret)]
                sqlite.executeMulti(sql, values)
            else:
                for value in values:
                    if value[1] == 'appId':
                        sql = "update sys_config set content=? where code='appId'"
                        value = (appId,)
                        sqlite.executeOne(sql, value)
                        continue
                    if value[1] == 'appSecret':
                        sql = "update sys_config set content=? where code='appSecret'"
                        value = (appSecret,)
                        sqlite.executeOne(sql, value)
                        continue

    def api(self, params):
        apiKey = params['apiKey']

        if apiKey != 'stable_token' and apiKey != 'set_key' \
            and apiKey != 'get_key' and apiKey != 'set_db' \
            and apiKey != 'get_db':
            if hasattr(self, 'accessToken')==False or \
                    self.accessToken == None or len(self.accessToken) == 0:
                self.task()

        if apiKey == 'stable_token':
            data = self.stable_token()
            return result.makeSuccess(data)
        elif apiKey == 'add_material':
            data = self.add_material(params)
            return result.makeSuccess(data)
        elif apiKey == 'get_materialcount':
            data = self.get_materialcount(params)
            return result.makeSuccess(data)
        elif apiKey == 'batchget_material':
            data = self.batchget_material(params)
            return result.makeSuccess(data)
        elif apiKey == 'get_key':
            data = self.get_key()
            return result.makeSuccess(data)
        elif apiKey == 'set_key':
            self.set_key(params['body']['appId'],
                         params['body']['appSecret'])
            self.startTask()
            return result.makeSuccess('success')
        elif apiKey == 'set_db':
            self.set_db(params)
            return result.makeSuccess('success')

        elif apiKey == 'get_db':
            data = self.get_db()
            return result.makeSuccess(data)

    def get_key(self):
        result = {"appId": self.appId, "appSecret": self.appSecret}
        sql = "select * from sys_config where code in('appId','appSecret')"
        values = sqlite.select(sql)

        if values != None and len(values) >1:
            for value in values:
                if value[1] == 'appId':
                    self.appId = value[2]
                    result['appId'] = self.appId
                    continue
                if value[1] == 'appSecret':
                    self.appSecret = value[2]
                    result['appSecret'] = self.appSecret
                    continue
            self.task()

        return result

    def get_db(self):
        return sqlite.path

    def set_db(self, params):
        sqlite.set_path(params['body']['path'])
        sql = "select * from sys_config where code in('appId','appSecret')"
        values = sqlite.select(sql)

        if values != None and len(values) >1:
            for value in values:
                if value[1] == 'appId':
                    self.appId = value[2]
                    continue
                if value[1] == 'appSecret':
                    self.appSecret = value[2]
                    continue
            self.task()

    def add_material(self, params):
        path = apiPath[params['apiKey']]['path']
        data = {
            "grant_type": params['body']['grant_type'],
            "appid": params['body']['appid'],
            "secret": params['body']['secret']
        }
        response = requests.post(url=path, json=data)
        return response.text

    def get_materialcount(self, params):
        path = apiPath[params['apiKey']]['path']
        path = path + "?access_token=" + self.accessToken
        response = requests.get(path)
        return response.text
    def batchget_material(self, params):
        path = apiPath[params['apiKey']]['path']
        path = path + "?access_token=" + self.accessToken
        data = {
            "type": params['body']['type'],
            "offset": params['body']['offset'],
            "count": params['body']['count']
        }
        response = requests.post(url=path, json=data)
        jsonObj = json.loads(response.text)
        for obj in jsonObj['item']:
            obj['name'] = obj['name'].encode('iso-8859-1').decode('utf8')
            if 'url' in obj:
                obj['url'] = obj['url'].replace("mmbiz.qpic.cn", "mpimg.webusi.net")
                continue
            if 'cover_url' in obj:
                obj['url'] = obj['cover_url'].replace("mmbiz.qpic.cn", "mpimg.webusi.net")
                continue
            obj['url'] = 'none'
        return jsonObj

    def stable_token(self):
        path = apiPath['stable_token']['path']
        data = {"grant_type": "client_credential",
                "appid": self.appId, "secret": self.appSecret}
        response = requests.post(url=path, json=data)
        return response.text

wechat = WeChat()
